Authorize and capture
A card payment happens in two moves. Authorization checks the card and holds the funds, Capture moves the funds. You choose whether these happen together or separately withcapture_mode:
INSTANTcaptures the moment authorization succeeds. Use it when you fulfill immediately, like digital goods.MANUALauthorizes now and waits for you to capture later. Ideal when you ship before charging, so you capture on dispatch.
Payments are asynchronous
Every payment action returns202 Accepted immediately with a payment id and a status of PENDING. lite processes the work in the background. The 202 means accepted for processing, not succeeded. Get the final outcome by retrieving the payment, following the _links returned on the response, or via your webhook events.
Payment status
A payment reports one of these states. The ones you’ll handle most areAUTHORIZED, CAPTURED, PARTIALLY_CAPTURED, VOIDED, REFUNDED, and FAILED.
| Status | Meaning |
|---|---|
CREATED | Created and queued for processing. |
PENDING | Being processed. |
AUTHORIZED | Funds held, not yet captured. |
CAPTURED | Full authorized amount captured. |
PARTIALLY_CAPTURED | Only part of the authorization was captured. |
VOIDED | Authorization reversed before capture. |
AUTHORIZATION_REVERSED | Authorization reversed by the system. |
EXPIRED | Authorization expired before capture. |
FAILED | Processing failed. |
REFUNDED | Fully refunded after capture. |
Before you begin
Authenticate withx-api-key. All examples use https://{{url}}/v1. Amounts are integer minor units (10000 is 100.00 SAR).
Optionally, use an x-idempotency-key (a UUID) on every create, capture, void, and refund, so a retried request does not charge twice. Add x-correlation-id (a UUID) to trace a request through logs and support.
Create a payment
POST /v1/payments
Required: amount, currency, and device. The device block (IP, user agent, screen, timezone, and so on) is mandatory because it feeds 3DS and risk assessment. Supply the card either as a stored instrument (payment_instrument.id) or as encrypted inline card data (payment_instrument.encrypted_instrument_data).
Key request fields
| Field | Required | Notes |
|---|---|---|
amount | Yes | Minor units, minimum 1. |
currency | Yes | ISO 4217. |
device | Yes | Browser and device data for 3DS and risk. All listed sub-fields are required. |
payment_instrument.id | Conditional | A stored instrument’s UUID. Use this to charge a saved card. |
payment_instrument.encrypted_instrument_data | Conditional | Encrypted inline card data, as an alternative to a stored instrument. |
capture_options.capture_mode | Conditional when capture_options is sent | INSTANT or MANUAL. Default is MANUAL. |
processing.processing_type | Conditional | REGULAR, CARD_ON_FILE, or UNSCHEDULED_CARD_ON_FILE. |
processing.initiator | Conditional | CARD_HOLDER (customer present) or MERCHANT (merchant-initiated). |
threeds.force | No | Force 3DS regardless of the risk engine assessment. |
threeds.data | No | Pre-authenticated 3DS results, if you ran 3DS yourself on different rails. |
order, customer, metadata, channel_id, return_info | No | Order detail, customer detail, your own metadata, channel, and redirect URLs for flows that need a 3DS redirect. |
Response
id. It identifies the payment for every capture, void, refund, and lookup. The _links tell you which actions are currently allowed, follow them rather than building the URLs by hand. A redirect link appears when the payment needs a 3DS challenge; send the customer there to complete it.
Charging a stored card (card on file)
To charge a saved instrument for a subscription or other merchant-initiated payment, reference the instrument and describe the transaction so it stays scheme-compliant:initiator: MERCHANT for payments you trigger without the cardholder present, and CARD_HOLDER when the customer is actively checking out. The agreement_id links back to the card-on-file agreement you set up when storing the instrument.
Capture an authorized payment
POST /v1/payments/{payment_id}/capture
Captures a payment that was authorized with MANUAL. Omit amount to capture the full authorization, or pass a smaller amount for a partial capture. For multiple partial captures, set metadata.is_final to true on the last one to release any remaining authorized funds.
Void an authorized payment
POST /v1/payments/{payment_id}/void
Reverses an authorization before it is captured, releasing the hold on the customer’s card. Once a payment is captured, void no longer applies, refund instead. The body is optional; include a reason to record why.
Refund a captured payment
POST /v1/payments/{payment_id}/refund
Returns funds after capture. Omit amount to refund the full remaining captured amount, or pass a smaller amount for a partial refund. You can refund multiple times up to the captured total.
Retrieve a payment
GET /v1/payments/{payment_id}
Fetch the current state of a payment. Expand related data with include=instrument,operations, where operations lists the authorizations, captures, voids, and refunds applied so far.
payment object and, when relevant, two extras:
next_action.redirect: present only when the payment needs the customer sent somewhere, the URL for a 3DS challenge.operations: the audit trail. Each entry is oneAUTHORIZE,CAPTURE,REFUND,VOID, orREVERSE, with its ownstatus(PENDING/SUCCESS/FAILURE), amount, and the underlying gateway response codes. This is where you see what happened and why a step failed.
payment_method, the channel the card ran through: CARD, the wallets (APPLE_PAY, GOOGLE_PAY, SAMSUNG_PAY), network tokens (VTS, SCOF). With include=instrument, the masked card detail (brand, last four, expiry) comes back too.
You can also look a payment up by your own order reference with GET /v1/payments/by-order/{order_reference} (same include options), and list a merchant’s payments with GET /v1/payments using pagination and filters.
Errors
| Code | Meaning |
|---|---|
400 | The request is invalid, or the action isn’t allowed in the payment’s current state (for example, capturing a payment that was never authorized). |
401 | Authentication failed. The API key or token is missing or invalid. |
403 | Blocked by security policy, including a payer whose country doesn’t match the client region. |
404 | No payment matches the given ID. |
500 | An unexpected server error. Retry with exponential backoff. |